﻿using System;
using System.Collections.Generic;
using CookComputing.XmlRpc;
//
using PerceptiveMCAPI.Types;
//
namespace PerceptiveMCAPI.Methods
{
	public class campaignEcommOrderAdd : Api_BaseExecute
	{
		private new campaignEcommOrderAddInput Input { get; set; }
		private campaignEcommOrderAddOutput Output { get; set; }
		// =============================================== constructors
		public campaignEcommOrderAdd() { }
		// ---------
		public campaignEcommOrderAdd( campaignEcommOrderAddInput input ) { Input = input; }
		// =============================================== Execute
		public campaignEcommOrderAddOutput Execute()
		{
			// empty constructor & Execute() is bad
			if ( Input == null )
				throw new ArgumentException( "Input class not provided" );
			// do the deed
			Output = Execute( Input );
			return Output;
		}
		// ---------------------------------------------
		public campaignEcommOrderAddOutput Execute( campaignEcommOrderAddInput input )
		{
			Input = input;
			Output = new campaignEcommOrderAddOutput( Input );
			ValidationIsOK = true;
			//-------------------------
			if ( Input.api_Validate )
			{
				Output.api_ValidatorMessages = ValidateInput.Validate( Input );
				ValidationIsOK = ValidateInput.IsOK( Output.api_ValidatorMessages );
			}
			//------------------------- do it
			if ( ValidationIsOK )
			{
				ApiRun( Input, input.parms.apikey );  // execute API & format output
			}
			// ---
			return Output;
		}

		#region ================================================================= API Calls

		// ---------------------------------------------------------- XmlRpc
		protected override void ExecuteXmlRpc()
		{
			try
			{
				XmlRpcStruct order = formatOrder( Input.parms.order );
				bool rpcResult = apiXmlRpc.api.campaignEcommOrderAdd( Input.parms.apikey, order );
				Output.Format( rpcResult );
			}
			catch ( XmlRpcFaultException fex )
			{
				Output.api_ErrorMessages.Add( apiException.FormatError( fex ) );
			}
			catch ( Exception ex )
			{
				Output.api_ErrorMessages.Add( apiException.FormatError( ex ) );
			}
		}

		private XmlRpcStruct formatOrder( ecommOrder order )
		{
			XmlRpcStruct rpc = new XmlRpcStruct();
			XmlRpcStruct itm; int i = -1;
			// -------------------------------------
			rpc.Add( "id", order.order_id ?? "" );
			rpc.Add( "campaign_id", order.campaign_id ?? "" );
			rpc.Add( "email_id", order.email_id ?? "" );
			rpc.Add( "total", order.total );
			if ( order.order_date > DateTime.MinValue )
				rpc.Add( "order_date", apiHelper.FormatApiDateParm( order.order_date ) );
			rpc.Add( "shipping", order.shipping );
			rpc.Add( "tax", order.tax );
			rpc.Add( "store_id", order.store_id ?? "" );
			rpc.Add( "store_name", order.store_name ?? "" );
			rpc.Add( "plugin_id", order.plugin_id ?? "" );
			object[] items = new object[order.items.Count];

			foreach ( var item in order.items )
			{
				i++;
				itm = new XmlRpcStruct();
				if ( item.line_num > 0 )
					itm.Add( "line_num", item.line_num );
				itm.Add( "product_id", item.product_id );
				itm.Add( "product_name", item.product_name ?? "" );
				itm.Add( "category_id", item.category_id );
				itm.Add( "category_name", item.category_name ?? "" );
				itm.Add( "qty", item.qty );
				itm.Add( "cost", item.cost );
				items[i] = itm;
				//
			}
			rpc.Add( "items", items );
			// -------------------------------------
			return rpc;
		}

		// ---------------------------------------------------------- Serial Post
		protected override void ExecuteSerialPost()
		{
			try
			{
				Dictionary<string, string> dict = new Dictionary<string, string>();
				dict.Add( "apikey", Input.parms.apikey );
				// --------------------------------- order format
				dict.Add( "order[id]", Input.parms.order.order_id ?? "" );
				dict.Add( "order[campaign_id]", Input.parms.order.campaign_id ?? "" );
				dict.Add( "order[email_id]", Input.parms.order.email_id ?? "" );
				dict.Add( "order[total]", Input.parms.order.total.ToString( "N2" ) );
				if ( Input.parms.order.order_date > DateTime.MinValue )
					dict.Add( "order[order_date]", apiHelper.FormatApiDateParm( Input.parms.order.order_date ) );
				dict.Add( "order[shipping]", Input.parms.order.shipping.ToString( "N2" ) );
				dict.Add( "order[tax]", Input.parms.order.tax.ToString( "N2" ) );
				dict.Add( "order[store_id]", Input.parms.order.store_id ?? "" );
				dict.Add( "order[store_name]", Input.parms.order.store_name ?? "" );
				dict.Add( "order[plugin_id]", Input.parms.order.plugin_id ?? "" );
				int i = -1;
				foreach ( var item in Input.parms.order.items )
				{
					i++;
					dict.Add( string.Format( "order[items][{0}][line_num]", i ), item.line_num.ToString() );
					dict.Add( string.Format( "order[items][{0}][product_id]", i ), item.product_id.ToString() );
					dict.Add( string.Format( "order[items][{0}][product_name]", i ), item.product_name ?? "" );
					dict.Add( string.Format( "order[items][{0}][category_id]", i ), item.category_id.ToString() );
					dict.Add( string.Format( "order[items][{0}][category_name]", i ), item.category_name ?? "" );
					dict.Add( string.Format( "order[items][{0}][qty]", i ), item.qty.ToString() );
					dict.Add( string.Format( "order[items][{0}][cost]", i ), item.cost.ToString( "N2" ) );
				}
				// -- do it
				string api_Request = "";
				string api_Response = apiSerial.ProcessRequest( Input, dict, out api_Request );
				Output.Format( api_Request, api_Response );
			}
			catch ( Exception ex )
			{
				Output.api_ErrorMessages.Add( apiException.FormatError( ex ) );
			}
		}

		#endregion
	}
}
